﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using NF.Core.SOM;

namespace NF.Clustering
{
    public class SOMPreview : Image
    {
        public SOMPreview()
        {
            ChannelIndices = new int[] { 0, 1, 2 };
        }

        public unsafe void Update(SelfOrganizingMap som)
        {
            if(mBitmap == null || mBitmap.PixelWidth != som.GridCols
                || mBitmap.PixelHeight != som.GridRows)
            {
                mBitmap = new WriteableBitmap(som.GridCols, som.GridRows, 96.0, 96.0, PixelFormats.Bgra32,
                    null);
            }

            int bufSize = mBitmap.PixelWidth * mBitmap.PixelHeight * 4;
            int stride = mBitmap.PixelWidth * 4;
            //byte* buf = stackalloc byte[bufSize];
            byte[] bufArray = new byte[bufSize];
            fixed (byte* buf = &bufArray[0])
            {
                byte* p;
                MapNode n;

                for (int j = 0; j < som.GridRows; ++j)
                {
                    p = buf + stride * j;

                    for (int i = 0; i < som.GridCols; ++i, p += 4)
                    {
                        n = som.GetMapNode(i, j);

                        p[0] = (byte)(n.W[ChannelIndices[2]] * 51.0);
                        p[1] = (byte)(n.W[ChannelIndices[1]] * 51.0);
                        p[2] = (byte)(n.W[ChannelIndices[0]] * 51.0);
                        p[3] = 0xff;
                    }
                }

                mBitmap.Lock();

                mBitmap.WritePixels(new Int32Rect(0, 0, mBitmap.PixelWidth, mBitmap.PixelHeight),
                    (IntPtr)(void*)buf, bufSize, stride, 0, 0);

                mBitmap.Unlock();
            }

            Source = mBitmap;
        }

        public int[] ChannelIndices
        {
            get;
            private set;
        }

        private WriteableBitmap mBitmap;
    }
}
